package cn.buk.tms.eotms.service;

import cn.buk.common.JsonResult;
import cn.buk.tms.common.constant.TmsOrderConstant;
import cn.buk.tms.eotms.dao.FlightOrderDao;
import cn.buk.tms.eotms.dao.OrderNoGenerator;
import cn.buk.tms.eotms.dao.RefundOrderDao;
import cn.buk.tms.eotms.dto.FlightRefundOrderDetailDto;
import cn.buk.tms.eotms.dto.FlightRefundOrderRequestDto;
import cn.buk.tms.eotms.dto.FlightRefundTicket;
import cn.buk.tms.eotms.dto.RoleInfo;
import cn.buk.tms.eotms.entity.*;
import cn.buk.tms.eotms.response.RefundOrderResponseDto;
import cn.buk.tms.eotms.sc.SearchFlightOrderCriteria;
import cn.buk.tms.eotms.util.FlightTicketUtil;
import cn.buk.tms.exception.BaseException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author yfdai
 */
@Service
public class RefundOrderServiceImpl extends BaseAbstractService implements RefundOrderService {

  @Autowired
  private RefundOrderDao refundOrderDao;

  @Autowired
  private OrderNoGenerator orderNoGenerator;

  @Autowired
  private FlightOrderDao flightOrderDao;


  @Override
  public List<RefundOrderResponseDto> searchRefundOrders(int userId, SearchFlightOrderCriteria sc) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);
    final int enterpriseId = getEnterpriseIdByUserId(userId);
    final String username = getUsernameByUserId(userId);

    Set<String> roles = getRolesByUserId(enterpriseId, userId);
    //管理员可以查看所有的员工信息
    //其它可以查看本部门所有的员工信息
    if (roles.contains(RoleInfo.ROLE_ADMIN)) {
      //管理员可以查看所有部门的订单
    } else if (roles.contains(RoleInfo.ROLE_MANAGER) || roles.contains(RoleInfo.ROLE_APPROVER)){
      //只能查看本部门的
      int deptId = getCustomerDeptIdByUserId(userId);
      sc.setDepartmentId(deptId);
    } else {
      //只能查看自己的订单
      sc.setOp1(username);
    }

    List<FlightRefundOrder> list = refundOrderDao.searchFlightRefundOrder(ownerId, customerId, sc);

    List<RefundOrderResponseDto> dtos = new ArrayList<>();
    for(FlightRefundOrder info : list) {
//      FlightOrderUtil.cleanFlightRefundOrder(info);
      dtos.add(RefundOrderResponseDto.createBy(info));
    }

    return dtos;
  }

  @Override
  public RefundOrderResponseDto getFlightRefundOrderDetail(final int userId, final int id) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);

    FlightRefundOrder o = refundOrderDao.getFlightRefundOrderDetail(id);

    if (o == null || o.getEnterpriseId() != ownerId || o.getCustomer().getId() != customerId) {
      RefundOrderResponseDto baseDto = new RefundOrderResponseDto();
      baseDto.setErrcode(400);
      baseDto.setErrmsg("不存在");
      return baseDto;
    }

    for(FlightRefundOrderDetail detail: o.getFlights()) {
      detail.setOrder(null);
    }

    RefundOrderResponseDto dto = RefundOrderResponseDto.createBy(o);

    dto.setErrcode(0);


    return dto;
  }

  @Override
  public JsonResult createFlightRefundOrder(final int userId, FlightRefundOrderRequestDto dto) throws BaseException {
    if (dto.getRefundTickets().size() < 1) {
      throw new BaseException(20024, "请选择需要退票的票号");
    }

    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);
    final String username = getUsernameByUserId(userId);

    int selectCount = 0;
    for(FlightRefundTicket t: dto.getRefundTickets()) {
      if (!t.isSelected()) {
        continue;
      }

      selectCount++;

      if (!FlightTicketUtil.verifyTicketNo(t.getTicketNo())
              && !FlightTicketUtil.verifyConnectionTicketNo(t.getTicketNo())
      ) {
        throw new BaseException(20025, "票号格式不符合要求");
      }

      final String balCode = t.getTicketNo().substring(0, 3);
      final String tickNo = getTenTicketNo(t.getTicketNo());

      // 检查该票号是否已经退票订单
      var sc = new SearchFlightOrderCriteria();
      sc.setBalCode(balCode);
      sc.setTicketNo(tickNo);
      List<FlightRefundOrder> orders = refundOrderDao.searchFlightRefundOrder(ownerId, customerId, sc);
      if (orders.size() > 0) {
        throw new BaseException(20026, balCode + tickNo + "-该票号已经创建了退票单");
      }

      //查找机票订单是否包含此票号
      var sc1 = new SearchFlightOrderCriteria();
      sc1.setTicketNo(tickNo);
      var flightOrders = flightOrderDao.searchOrder(ownerId, customerId, sc1);
      if (flightOrders.isEmpty()) {
        throw new BaseException(20030, balCode + tickNo + "-未找到和票号对应的机票订单");
      }
    }

    if (selectCount < 1) {
      throw new BaseException(20024, "请选择需要退票的票号");
    }

    int created = 0;
    int retCode = 0;
    for(FlightRefundTicket t: dto.getRefundTickets()) {
      if (!t.isSelected()) {
        continue;
      }

      final String balCode = t.getTicketNo().substring(0, 3);
      final String tickNo = getTenTicketNo(t.getTicketNo());

      if (StringUtils.isBlank(t.getName())) {
        throw new BaseException(20027, "退票乘机人的姓名");
      }

      if (StringUtils.isBlank(t.getIdNo())) {
        throw new BaseException(20028, "退票乘机人的证件号");
      }

      retCode = doCreateRefundOrder(ownerId, customerId, username, balCode, tickNo, t.getName(), t.getIdNo(), dto);
      if (retCode > 0) {
        created++;
      }
    }

    JsonResult jsonResult = JsonResult.createJsonResult(created);
    if (retCode > 0) {
      jsonResult.setReturnCode(retCode);
    } else if (retCode == -100) {
      jsonResult.setErrmsg("保存时出现错误，请检查是否已有退票单。");
    }

    return jsonResult;
  }

  /**
   * 获取10位票号(第一个10位）
   * @param tempTicketNo 可能是联程票号：781-1234567891-92
   * @return
   */
  private String getTenTicketNo(String tempTicketNo) {
    //删除前3位
    tempTicketNo = tempTicketNo.substring(3);
    if ("-".equalsIgnoreCase(tempTicketNo.substring(0, 1))) {
      tempTicketNo = tempTicketNo.substring(1);
    }

    return tempTicketNo.substring(0, 10);
  }

  private int doCreateRefundOrder(final int ownerId, final int customerId, final String username, final String balCode, final String tickNo,
                                  final String psgName, final String idNo, final FlightRefundOrderRequestDto dto) throws BaseException {
    FlightRefundOrder info = new FlightRefundOrder();

    info.setEnterpriseId(ownerId);
    info.setBalanceCode(balCode);
    info.setTicketNo(tickNo);

    info.setPsgName(psgName);
    info.setIdNo(idNo);

    info.setParvalue(dto.getParValue());
    info.setTax(dto.getTax());
    info.setTicketAmount(dto.getAmount());

    info.setRemark(dto.getRemark());
    info.setOperator(username);

    info.setReasonCode(dto.getReasonCode());
    info.setReasonDesc(dto.getReasonDesc());

    info.setOrderId(dto.getOrderId());
    info.setOrderNo(dto.getOrderNo());

    info.setIntlTicket(dto.getIntlTicket());

    info.setRefundOrderNo(orderNoGenerator.generateOrderNo(ownerId, TmsOrderConstant.ORDER_NO_FLIGHT_REFUND_SELF_SERVICE));

    if (dto.getOrderId() > 0 || dto.getOrderNo().length() > 0) {
      FlightOrder flightOrder = null;
      if (dto.getOrderId() > 0) {
        flightOrder = flightOrderDao.getOrderById(dto.getOrderId());
      } else if (dto.getOrderNo().length() > 0) {
        flightOrder = flightOrderDao.getOrderByOrderNo(ownerId, dto.getOrderNo());
      }

      if (flightOrder != null) {
        info.setCostCenter(flightOrder.getCostCenter());
        info.setProjectName(flightOrder.getProjectName());

        info.setPayType(flightOrder.getPayType());
        info.setPayRemark(flightOrder.getPayRemark());
        info.setPnrNo(flightOrder.getPnrNo());
      }
   }

    //企业客户
    info.setCustomerType(1);
    Customer customer = new Customer();
    customer.setId(customerId);
    info.setCustomer(customer);

    if (dto.getFlights().isEmpty()) {
      throw new BaseException(20028, "退票的航班信息");
    }

    for(var detailDto: dto.getFlights()) {
      if (!detailDto.isSelected()) {
        continue;
      }

      if (StringUtils.isBlank(detailDto.getDport()) || StringUtils.isBlank(detailDto.getAport())) {
        throw new BaseException(20031, "退票的航班信息需要包含出发机场和到达机场");
      }

      var detail = new FlightRefundOrderDetail();
      detail.setOrder(info);
      detail.setEnterpriseId(ownerId);

      FlightInfo flt = detail.getFlight();

      flt.setDepartureAirport(detailDto.getDport());
      flt.setDepartureAirportName(detailDto.getDportName());
      flt.setDepartureTerminal(detailDto.getDterm());
      flt.setArrivalAirport(detailDto.getAport());
      flt.setArrivalAirportName(detailDto.getAportName());
      flt.setArrivalTerminal(detailDto.getAterm());
      flt.setDepartureDate(detailDto.getDdate());
      flt.setDepartureTime(detailDto.getDtime());
      flt.setArrivalTime(detailDto.getAtime());
      flt.setSubclass(detailDto.getSubclass());
      flt.setFlightNo(detailDto.getFlightNo());

      info.getFlights().add(detail);
    }

    if (info.getFlights().isEmpty()) {
      throw new BaseException(20028, "请选择退票的航班信息");
    }

    int retCode = refundOrderDao.createFlightRefundOrder(info);

    return retCode;
  }

}
